#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>

#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<signal.h>

#include "StdTcp.h"
#include "StdThread.h"
#include "DoubleLinkList.h"
#include "ThreadPool.h"
#include "login.h"
#include "StdFile.h"

#define true 1
#define false 0


void SignalHandle(int signum);
struct Message
{
    int flag;
    int flag2;
    int flag3;
    char fromName[20];
    char toName[20];
    char content[1024];
    char groupName[100];
    char Filecontent[1024]; //
    char fileName[100];
    size_t fileSize;
};
typedef struct Message Msg;


struct Client
{
    int sock;
    char name[20];
};
typedef struct Client C;

C *CreateClient(int sock,const char *name)
{
    C*c = (C*)malloc(sizeof(C));
    if(c == NULL)
    {
        printf("CreateClient malloc error\n");
        return NULL;
    }
    c->sock = sock;
    strcpy(c->name,name);
    return c;
}

void FreeClient(C *c)
{
    if(c != NULL)
    {
        free(c);
    }
}

DLlist list;


void*thread_handler(void *arg)
{
    int sock = *((int *)arg);
    while(1)
    {
        Msg msg = {0,0,0,0,0};
        TcpServerRecv(sock,&msg,sizeof(msg));
        if(msg.flag == 1)
        {

            printf("一位用户登录，用户名为[%s]\n",msg.fromName);
            InsertTail(&list,CreateClient(sock,msg.fromName));
            InsertOnlineUser(msg.fromName);
        }

        else if(msg.flag == 2)
        {
            if(msg.flag2 == 1)
            {
                printf("用户[%s]给用户[%s]发送了一条消息\n",\
                msg.fromName,msg.toName);
                // printf("%s\n",msg.groupName);
                ChatRecordSaved(msg.fromName,msg.content,msg.toName);

                struct Node *travelPoint = list.head;
                while(travelPoint != NULL)
                {
                    C* c = (C *)travelPoint->data;
                    if(strcmp(c->name,msg.toName) == 0)
                    {
                        TcpServerSend(c->sock,&msg,sizeof(msg));
                        break;
                    } 
                    travelPoint = travelPoint->next;
                }
            }
            else if(msg.flag2 == 2)
            {
                printf("用户[%s]群发了一条消息\n",msg.fromName);
                struct Node* travelPoint1 = list.head;
                while (travelPoint1 != NULL)
                {
                    C* c = (C *)travelPoint1->data;
                    if(strcmp(c->name,msg.fromName) != 0)
                    {
                        TcpServerSend(c->sock,&msg,sizeof(msg));
                    } 
                    travelPoint1 = travelPoint1->next;
                }
            }
        }
        else if(msg.flag == 4)
        {
            if(msg.flag2 == 2)
            {
                printf("[%s]给[%s]发送了一条加群申请\n",msg.fromName,msg.toName);
                struct Node* travelPoint2 = list.head;
                while(travelPoint2 != NULL)
                {
                    C* c = (C *)travelPoint2->data;
                    if(strcmp(c->name,msg.toName) == 0)
                    {
                        TcpServerSend(c->sock,&msg,sizeof(msg));
                        break;
                    } 
                    travelPoint2 = travelPoint2->next;
                }
            }
            else if(msg.flag2 == 3)
            {
                insertGroupChat(msg.fromName,msg.content,msg.groupName);
                printf("[%s]在群[%s]发送了一条消息\n",msg.fromName,msg.groupName);

                DLlist *list2 = GetGroupMembers(msg.groupName);

                DLlist *list3 = FindGroupIntersection(&list,list2);
                
                struct Node *travelPoint3 = list3->head;
                while(travelPoint3 != NULL)
                {
                    C *c = (C*)travelPoint3->data;
                    TcpServerSend(c->sock,&msg,sizeof(msg));
                    travelPoint3 = travelPoint3->next;
                }
                FreeDLlist(list2);
                FreeDLlist(list3);
            }
            else if(msg.flag2 == 4)//bug
            {
                printf("[%s]上传了群文件[%s],请打开群文件查看\n",msg.fromName,msg.fileName);
                char sql[1024] = {0};
                sprintf(sql, "./QQgroup/GroupFile/%s/%s",msg.groupName,msg.fileName);
                int k = IsFileExist(sql);
                char newName[100];
                strcpy(newName,sql);
                while( k == true)
                {
                    strcpy(newName,".");
                    char TargetName[100] = {0};//新建一个字符数组，用于分割
                    strcpy(TargetName,sql);

                    char *fileName = strtok(TargetName,".");
                    char *backName = strtok(NULL,".");

                    strcat(newName,fileName);
                    strcat(newName,"_new.");
                    strcat(newName,backName);
                    k = IsFileExist(newName);
                }
                //printf("newname = %s\n",newName);
                WriteToFile(newName,msg.Filecontent,msg.fileSize);
            }
            else if(msg.flag2 == 5)
            {
                struct Node *travelPoint10 = list.head;
                while(travelPoint10 != NULL)
                {
                    C* c = (C *)travelPoint10->data;
                    if(strcmp(c->name,msg.toName) == 0)
                    {
                        TcpServerSend(c->sock,&msg,sizeof(msg));
                        break;
                    } 
                    travelPoint10 = travelPoint10->next;
                }
            }
        }
        else if(msg.flag == 5)
        {
            if(msg.flag2 == 1)
            {
                printf("用户[%s]给用户[%s]发送一个好友申请\n",msg.fromName,msg.toName);
                struct Node* travelPoint2 = list.head;
                while(travelPoint2 != NULL)
                {
                    C* c = (C *)travelPoint2->data;
                    if(strcmp(c->name,msg.toName) == 0)
                    {
                        TcpServerSend(c->sock,&msg,sizeof(msg));
                        break;
                    } 
                    travelPoint2 = travelPoint2->next;
                }
            }
            else if(msg.flag2 == 2)
            {
                //printf("%s  %s  %ld\n",msg.Filecontent,msg.fileName,msg.fileSize);
                printf("用户[%s]给用户[%s]发送了一个文件\n",msg.fromName,msg.toName);
                
                struct Node* travelPoint3 = list.head;
                while(travelPoint3 != NULL)
                {
                    C* c = (C *)travelPoint3->data;
                    if(strcmp(c->name,msg.toName) == 0)
                    {
                        TcpServerSend(c->sock,&msg,sizeof(msg));
                        break;
                    } 
                    travelPoint3 = travelPoint3->next;
                }
            }
            else if(msg.flag2 == 4)
            {
                struct Node *travelPoint10 = list.head;
                while(travelPoint10 != NULL)
                {
                    C* c = (C *)travelPoint10->data;
                    if(strcmp(c->name,msg.toName) == 0)
                    {
                        TcpServerSend(c->sock,&msg,sizeof(msg));
                        break;
                    } 
                    travelPoint10 = travelPoint10->next;
                }
            }
        }
       
        else if(msg.flag == 9)
        {
            printf("以知晓客户[%s]的下线请求,正在处理请等候\n",msg.fromName);
            DeleteOnlineUser(msg.fromName);
            
            sleep(1);
            printf("[%s]已下线\n",msg.fromName);
            pthread_exit(NULL);  
        }
    }
}


int main(int argc,char **argv)
{
    signal(SIGINT,SignalHandle);
    if(argc != 3)
    {
        printf("invalid input\n");
        return -1;
    }
    
    
    InitDLlist(&list);
    ThreadP *p = InitThreadPool(1000,2000,1000);
    if(p == NULL)
    {
        printf("threadp init error\n");
        return -1;
    }

    TcpS*s = InitTcpServer(argv[1],atoi(argv[2]));
    
    if(s == NULL)
    {
        printf("s is empty pointer\n");
        return -1;
    }
    int acceptSock = 0;
    int p5 =0;
    while((acceptSock = TcpServerAccept(s)) != -1)
    {
        p5++;
        ThreadP_AddTask(p,thread_handler,&acceptSock);
        printf("client :%d\n",acceptSock);
        printf("client2 :%d\n",p5);
    }
    DestoryThreadPool(p);
    return 0;
}

void SignalHandle(int signum)
{
    FreeDLlist(&list);
    printf("程序已经正常退出\n");
    exit(0);
}